package com.fowo.api.syncAmazon.api;

import cn.hutool.core.date.DateUtil;
import com.amazon.spapi.api.ReportsApi;
import com.amazon.spapi.model.reports.CreateReportSpecification;
import com.amazon.spapi.model.reports.Report;
import com.amazon.spapi.model.reports.ReportDocument;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fowo.api.datainterface.entity.DatainterfaceAuthority;
import com.fowo.api.datainterface.service.DatainterfaceAuthorityService;
import com.fowo.api.entity.*;
import com.fowo.api.mapper.ListingFatherMapper;
import com.fowo.api.service.impl.ShopInfoServiceImpl;
import com.fowo.api.service.impl.TmpFbaInventoryServiceImpl;
import com.fowo.api.service.impl.WarehouseServiceImpl;
import com.fowo.api.syncAmazon.util.AmazonUtil;
import com.fowo.api.syncAmazon.util.AmzDateUtils;
import com.fowo.api.syncAmazon.util.GeneralUtil;
import com.squareup.okhttp.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.*;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.util.*;
import java.util.stream.Collectors;
import java.util.zip.GZIPInputStream;

@Component
@Slf4j
public class FBAInventoryReportService extends ReportService {

    @Resource
    private DatainterfaceAuthorityService datainterfaceAuthorityBaseService;
    @Resource
    private AmazonUtil amazonUtil;
    @Resource
    private ShopInfoServiceImpl shopInfoService;
    @Resource
    private ListingFatherMapper listingFatherMapper;
    @Resource
    private TmpFbaInventoryServiceImpl tmpFbaInventoryService;
    @Resource
    private WarehouseServiceImpl warehouseService;

    /**
     * 仓库-FBA库存数据源： 《Reserved inventory 》报表
     * reserved_transfers：待调仓；
     * reserved_processing：调仓中；
     * reserved_customerorders：待发货；
     * 《Manage FBA inventory》报表
     * afn_inbound working_quantity：计划入库；
     * afn_inbound shipped_quantity：在途；
     * afn_inbound receiving_quantity：入库中；
     * afn_unsellable_quantity：不可售；
     * afn_fulfillable_quantity：可售；
     * 《FBA inventory》报表：库龄。
     * @throws Exception
     */
    public void getFbaInventory() throws Exception {
        DatainterfaceAuthority entityAuthority = datainterfaceAuthorityBaseService.getOne(Wrappers.<DatainterfaceAuthority>lambdaQuery().eq(DatainterfaceAuthority::getAppCode,"Amazon"), false);
        //管理亚马逊物流库存报告
        List<TmpFbaInventory> manageList = getManageFbaInventory(entityAuthority);
        //预留库存报告
        List<TmpFbaInventory> reservedList = getReservedInventory(entityAuthority);

//        List<TmpFbaInventory> manageList = new ArrayList<>();

        final List<TmpFbaInventory> fbaInventoryList = manageList.stream().map(m -> {
            reservedList.stream()
                    .filter(r -> r.getSid().equals(m.getSid()) && r.getAsin().equals(m.getAsin()) && r.getMsku().equals(m.getMsku()))
                    .forEach(r -> {
                        m.setWarehouseToBeAdjusted(m.getWarehouseToBeAdjusted() + r.getWarehouseToBeAdjusted());
                        m.setDuringWarehouseAdjustment(m.getDuringWarehouseAdjustment() + r.getDuringWarehouseAdjustment());
                        m.setToBeShipped(m.getToBeShipped() + r.getToBeShipped());
                    });
            return m;
        }).collect(Collectors.toList());
        tmpFbaInventoryService.saveBatch(fbaInventoryList);
        //亚马逊物流库存报告
//        getFBAInventory(entityAuthority);
    }

    /**
     * 管理亚马逊物流库存报告
     * @throws Exception
     */
    public List<TmpFbaInventory> getManageFbaInventory(DatainterfaceAuthority entityAuthority) throws Exception {
        List<TmpFbaInventory> tmpList = new ArrayList<>();

        final List<ShopInfo> list = shopInfoService.list(Wrappers.lambdaQuery(ShopInfo.class)
                .eq(ShopInfo::getPlatform,"Amazon")
                .eq(ShopInfo::getSellerAuthStatus,"SQ01"));
        for(ShopInfo shop : list){

            List<String> marketplaceIds = Arrays.asList(shop.getMarketplaceId().split(","));

            CreateReportSpecification body = new CreateReportSpecification();
            body.setReportType("GET_FBA_MYI_UNSUPPRESSED_INVENTORY_DATA");
            body.setMarketplaceIds(marketplaceIds);
            body.setDataStartTime(AmzDateUtils.getOffsetDateTimeUTC(DateUtil.beginOfDay(new Date())));
            body.setDataEndTime(AmzDateUtils.getOffsetDateTimeUTC(new Date()));

//            Calendar cstart=Calendar.getInstance();
//            cstart.add(Calendar.DATE, -360);
//            body.setDataStartTime(AmzDateUtils.getOffsetDateTimeUTC(cstart));
//            Calendar cend=Calendar.getInstance();
//            body.setDataEndTime(AmzDateUtils.getOffsetDateTimeUTC(cend));

            try {
                // 第一步 创建报告
                ReportsApi reportsApi = amazonUtil.getReportsApi(entityAuthority, shop, 0.0167);
                final String reportId = createReport(reportsApi, body);
                // 第二步 检验报告是否完成
                ReportsApi reportsApi2 = amazonUtil.getReportsApi(entityAuthority, shop, 2.0);
                final Report report = getReport(reportsApi2, reportId);
                // 第三步 获取报告连接
                ReportsApi reportsApi3 = amazonUtil.getReportsApi(entityAuthority, shop, 0.0167);
                final ReportDocument reportDocument = reportsApi3.getReportDocument(report.getReportDocumentId());
                // 第四步 下载报告
                String compressionAlgorithm = null;
                if (null != reportDocument.getCompressionAlgorithm()) {
                    compressionAlgorithm = reportDocument.getCompressionAlgorithm().getValue();
                }
                tmpList.addAll(downloadManageFbaInventory(reportDocument.getUrl(), compressionAlgorithm, shop));
            }catch (Exception e){
                log.error("店铺："+shop.getShopName()+" 获取亚马逊物流库存报告异常",e);
            }

        }
        return tmpList;
    }

    @Override
    public void download(String url, String compressionAlgorithm, ShopInfo shop) throws IOException, IllegalArgumentException {
//        OkHttpClient httpclient = new OkHttpClient();
//        Request request = new Request.Builder()
//                .url(url)
//                .get()
//                .build();
//
//        Response response = httpclient.newCall(request).execute();
//        if (!response.isSuccessful()) {
//            System.out.println(
//                    String.format("Call to download content was unsuccessful with response code: %d and message: %s",
//                            response.code(), response.message()));
//            return;
//        }
//
//        try (ResponseBody responseBody = response.body()) {
//            MediaType mediaType = MediaType.parse(response.header("Content-Type"));
//            Charset charset = mediaType.charset();
//            if (charset == null) {
//                throw new IllegalArgumentException(String.format(
//                        "Could not parse character set from '%s'", mediaType.toString()));
//            }
//
//            Closeable closeThis = null;
//            try {
//                InputStream inputStream = responseBody.byteStream();
//                closeThis = inputStream;
//
//                if ("GZIP".equals(compressionAlgorithm)) {
//                    inputStream = new GZIPInputStream(inputStream);
//                    closeThis = inputStream;
//                }
//
//                // This example assumes that the download content has a charset in the content-type header, e.g.
//                // text/plain; charset=UTF-8
//                if ("text".equals(mediaType.type()) && "plain".equals(mediaType.subtype())) {
//                    InputStreamReader inputStreamReader = new InputStreamReader(inputStream, charset);
//                    closeThis = inputStreamReader;
//
//                    BufferedReader reader = new BufferedReader(inputStreamReader);
//                    closeThis = reader;
//
//                    int lineNumber = 0;
//                    String line;
//                    Map<String,Integer> titleList = new HashMap<String,Integer>();
//                    List<TmpFbaInventory> list = new ArrayList<>();
//                    final List<ListingFather> listingFathers = listingFatherMapper.selectList(Wrappers.lambdaQuery(ListingFather.class).eq(ListingFather::getShop, shop.getId()));
//                    final Warehouse warehouse = warehouseService.getOne(Wrappers.lambdaQuery(Warehouse.class).eq(Warehouse::getSid, shop.getId()));
//                    while ((line = reader.readLine()) != null) {
//                        String[] info = line.split("\t");
//                        int length = info.length;
//                        if (lineNumber == 0) {
//                            for (int i = 0; i < length; i++) {
//                                titleList.put(info[i],i);
//                            }
//                        } else {
//                            TmpFbaInventory tmp = new TmpFbaInventory();
//                            tmp.setCreateTime(new Date());
//                            String sku= GeneralUtil.getStrValue(info, titleList, "sku");
//                            String fnsku= GeneralUtil.getStrValue(info, titleList, "fnsku");
//                            String asin= GeneralUtil.getStrValue(info, titleList, "asin");
//                            String product_name= GeneralUtil.getStrValue(info, titleList, "product-name");
//                            String condition= GeneralUtil.getStrValue(info, titleList, "condition");
//                            BigDecimal your_price= GeneralUtil.getBigDecimalValue(info, titleList, "your-price");
//                            String mfn_listing_exists= GeneralUtil.getStrValue(info, titleList, "mfn-listing-exists");
//                            Integer mfn_fulfillable_quantity= GeneralUtil.getIntegerValue(info, titleList, "mfn-fulfillable-quantity");
//                            String afn_listing_exists= GeneralUtil.getStrValue(info, titleList, "afn-listing-exists");
//                            Integer afn_warehouse_quantity= GeneralUtil.getIntegerValue(info, titleList, "afn-warehouse-quantity");
//                            Integer afn_fulfillable_quantity= GeneralUtil.getIntegerValue(info, titleList, "afn-fulfillable-quantity");
//                            Integer afn_unsellable_quantity= GeneralUtil.getIntegerValue(info, titleList, "afn-unsellable-quantity");
//                            Integer afn_reserved_quantity= GeneralUtil.getIntegerValue(info, titleList, "afn-reserved-quantity");
//                            Integer afn_total_quantity= GeneralUtil.getIntegerValue(info, titleList, "afn-total-quantity");
//                            BigDecimal per_unit_volume= GeneralUtil.getBigDecimalValue(info, titleList, "per-unit-volume");
//                            Integer afn_inbound_working_quantity= GeneralUtil.getIntegerValue(info, titleList, "afn-inbound-working-quantity");
//                            Integer afn_inbound_shipped_quantity= GeneralUtil.getIntegerValue(info, titleList, "afn-inbound-shipped-quantity");
//                            Integer afn_inbound_receiving_quantity= GeneralUtil.getIntegerValue(info, titleList, "afn-inbound-receiving-quantity");
//                            Integer afn_researching_quantity= GeneralUtil.getIntegerValue(info, titleList, "afn-researching-quantity");
//                            Integer afn_reserved_future_supply= GeneralUtil.getIntegerValue(info, titleList, "afn-reserved-future-supply");
//                            Integer afn_future_supply_buyable= GeneralUtil.getIntegerValue(info, titleList, "afn-future-supply-buyable");
//
//                            final ListingFather listingFather = listingFathers.stream()
//                                    .filter(l -> l.getShop().equals(shop.getId()) && l.getAsin().equals(asin) && l.getMsku().equals(sku))
//                                    .findAny()
//                                    .orElse(new ListingFather());
//
//                            tmp.setWarehouse(warehouse.getId());
//                            tmp.setPicture(listingFather.getImg());
//                            tmp.setAsin(asin);
//                            tmp.setMsku(sku);
//                            tmp.setFnsku(fnsku);
//                            tmp.setListingId(listingFather.getId());
//                            tmp.setProductId(listingFather.getPairProduct());
//                            tmp.setSku(listingFather.getSku());
//                            tmp.setHead(listingFather.getPrincipal());
//
//                            tmp.setFbaAvailableForSale(afn_fulfillable_quantity);
//                            tmp.setFbmAvailableForSale(mfn_fulfillable_quantity);
//                            if(mfn_listing_exists.equals("Yes")){
//                                tmp.setFulfillmentChannelType("FBM");
//                            }else if(afn_listing_exists.equals("Yes")){
//                                tmp.setFulfillmentChannelType("FBA");
//                            }
//                            tmp.setWarehouseToBeAdjusted(0);
//                            tmp.setDuringWarehouseAdjustment(0);
//                            tmp.setToBeShipped(0);
//                            tmp.setPlannedWarehousing(afn_inbound_working_quantity);
//                            tmp.setStandardInTransit(afn_inbound_shipped_quantity);
//                            tmp.setActualInTransit(0);
//                            tmp.setInStorage(afn_inbound_receiving_quantity);
//                            tmp.setNotAvailableForSale(afn_unsellable_quantity);
//                            tmp.setUnderInvestigation(afn_researching_quantity);
//                            tmp.setWarningStatus("");
//
//                            list.add(tmp);
//                        }
//                        lineNumber++;
//                        // Process line by line.
//                    }
//                    tmpFbaInventoryService.saveBatch(list);
//                } else {
//                    //Handle content with binary data/other media types here.
//                }
//            } catch (IOException e) {
//                // TODO Auto-generated catch block
//                log.error("处理亚马逊物流库存报告数据异常",e);
//            } finally {
//                if (closeThis != null) {
//                    closeThis.close();
//                }
//            }
//        }
    }

    public List<TmpFbaInventory> downloadManageFbaInventory(String url, String compressionAlgorithm, ShopInfo shop) throws IOException, IllegalArgumentException {
        List<TmpFbaInventory> list = new ArrayList<>();
        OkHttpClient httpclient = new OkHttpClient();
        Request request = new Request.Builder()
                .url(url)
                .get()
                .build();

        Response response = httpclient.newCall(request).execute();
        if (!response.isSuccessful()) {
            System.out.println(
                    String.format("Call to download content was unsuccessful with response code: %d and message: %s",
                            response.code(), response.message()));
            return list;
        }

        try (ResponseBody responseBody = response.body()) {
            MediaType mediaType = MediaType.parse(response.header("Content-Type"));
            Charset charset = mediaType.charset();
            if (charset == null) {
                throw new IllegalArgumentException(String.format(
                        "Could not parse character set from '%s'", mediaType.toString()));
            }

            Closeable closeThis = null;
            try {
                InputStream inputStream = responseBody.byteStream();
                closeThis = inputStream;

                if ("GZIP".equals(compressionAlgorithm)) {
                    inputStream = new GZIPInputStream(inputStream);
                    closeThis = inputStream;
                }

                // This example assumes that the download content has a charset in the content-type header, e.g.
                // text/plain; charset=UTF-8
                if ("text".equals(mediaType.type()) && "plain".equals(mediaType.subtype())) {
                    InputStreamReader inputStreamReader = new InputStreamReader(inputStream, charset);
                    closeThis = inputStreamReader;

                    BufferedReader reader = new BufferedReader(inputStreamReader);
                    closeThis = reader;

                    int lineNumber = 0;
                    String line;
                    Map<String,Integer> titleList = new HashMap<String,Integer>();
//                    List<TmpFbaInventory> list = new ArrayList<>();
                    final List<ListingFather> listingFathers = listingFatherMapper.selectList(Wrappers.lambdaQuery(ListingFather.class).eq(ListingFather::getShop, shop.getId()));
                    final Warehouse warehouse = warehouseService.getOne(Wrappers.lambdaQuery(Warehouse.class).eq(Warehouse::getSid, shop.getId()));
                    Long wid = null;
                    if(null != warehouse){
                        wid = warehouse.getId();
                    }
                    while ((line = reader.readLine()) != null) {
                        String[] info = line.split("\t");
                        int length = info.length;
                        if (lineNumber == 0) {
                            for (int i = 0; i < length; i++) {
                                titleList.put(info[i],i);
                            }
                        } else {
                            TmpFbaInventory tmp = new TmpFbaInventory();
                            tmp.setCreateTime(new Date());
                            String sku= GeneralUtil.getStrValue(info, titleList, "sku");
                            String fnsku= GeneralUtil.getStrValue(info, titleList, "fnsku");
                            String asin= GeneralUtil.getStrValue(info, titleList, "asin");
                            String product_name= GeneralUtil.getStrValue(info, titleList, "product-name");
                            String condition= GeneralUtil.getStrValue(info, titleList, "condition");
                            BigDecimal your_price= GeneralUtil.getBigDecimalValue(info, titleList, "your-price");
                            String mfn_listing_exists= GeneralUtil.getStrValue(info, titleList, "mfn-listing-exists");
                            Integer mfn_fulfillable_quantity= GeneralUtil.getIntegerValue(info, titleList, "mfn-fulfillable-quantity");
                            String afn_listing_exists= GeneralUtil.getStrValue(info, titleList, "afn-listing-exists");
                            Integer afn_warehouse_quantity= GeneralUtil.getIntegerValue(info, titleList, "afn-warehouse-quantity");
                            Integer afn_fulfillable_quantity= GeneralUtil.getIntegerValue(info, titleList, "afn-fulfillable-quantity");
                            Integer afn_unsellable_quantity= GeneralUtil.getIntegerValue(info, titleList, "afn-unsellable-quantity");
                            Integer afn_reserved_quantity= GeneralUtil.getIntegerValue(info, titleList, "afn-reserved-quantity");
                            Integer afn_total_quantity= GeneralUtil.getIntegerValue(info, titleList, "afn-total-quantity");
                            BigDecimal per_unit_volume= GeneralUtil.getBigDecimalValue(info, titleList, "per-unit-volume");
                            Integer afn_inbound_working_quantity= GeneralUtil.getIntegerValue(info, titleList, "afn-inbound-working-quantity");
                            Integer afn_inbound_shipped_quantity= GeneralUtil.getIntegerValue(info, titleList, "afn-inbound-shipped-quantity");
                            Integer afn_inbound_receiving_quantity= GeneralUtil.getIntegerValue(info, titleList, "afn-inbound-receiving-quantity");
                            Integer afn_researching_quantity= GeneralUtil.getIntegerValue(info, titleList, "afn-researching-quantity");
                            Integer afn_reserved_future_supply= GeneralUtil.getIntegerValue(info, titleList, "afn-reserved-future-supply");
                            Integer afn_future_supply_buyable= GeneralUtil.getIntegerValue(info, titleList, "afn-future-supply-buyable");

                            final ListingFather listingFather = listingFathers.stream()
                                    .filter(l -> l.getShop().equals(shop.getId()) && l.getAsin().equals(asin) && l.getMsku().equals(sku))
                                    .findAny()
                                    .orElse(new ListingFather());

                            tmp.setWarehouse(wid);
                            tmp.setSid(shop.getId());
                            tmp.setPicture(listingFather.getImg());
                            tmp.setAsin(asin);
                            tmp.setMsku(sku);
                            tmp.setFnsku(fnsku);
                            tmp.setListingId(listingFather.getId());
                            tmp.setProductId(listingFather.getPairProduct());
                            tmp.setSku(listingFather.getSku());
                            tmp.setHead(listingFather.getPrincipal());

                            tmp.setFbaAvailableForSale(afn_fulfillable_quantity);
                            tmp.setFbmAvailableForSale(mfn_fulfillable_quantity);
                            if(mfn_listing_exists.equals("Yes")){
                                tmp.setFulfillmentChannelType("FBM");
                            }else if(afn_listing_exists.equals("Yes")){
                                tmp.setFulfillmentChannelType("FBA");
                            }
                            tmp.setWarehouseToBeAdjusted(0);
                            tmp.setDuringWarehouseAdjustment(0);
                            tmp.setToBeShipped(0);
                            tmp.setPlannedWarehousing(afn_inbound_working_quantity);
                            tmp.setStandardInTransit(afn_inbound_shipped_quantity);
                            tmp.setActualInTransit(0);
                            tmp.setInStorage(afn_inbound_receiving_quantity);
                            tmp.setNotAvailableForSale(afn_unsellable_quantity);
                            tmp.setUnderInvestigation(afn_researching_quantity);
                            tmp.setWarningStatus("");

//                            tmp.setTotalInventory(afn_fulfillable_quantity+afn_inbound_shipped_quantity+afn_inbound_receiving_quantity);
//                            tmp.setAvailableStock(afn_fulfillable_quantity+afn_inbound_receiving_quantity);

                            list.add(tmp);
                        }
                        lineNumber++;
                        // Process line by line.
                    }
                    tmpFbaInventoryService.saveBatch(list);
                } else {
                    //Handle content with binary data/other media types here.
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                log.error("处理亚马逊物流库存报告数据异常",e);
            } finally {
                if (closeThis != null) {
                    closeThis.close();
                }
            }
        }
        return list;
    }

    /**
     * 预留库存报告
     * @param entityAuthority
     * @throws Exception
     */
    public List<TmpFbaInventory> getReservedInventory (DatainterfaceAuthority entityAuthority) throws Exception {
        List<TmpFbaInventory> tmpList = new ArrayList<>();

        final List<ShopInfo> list = shopInfoService.list(Wrappers.lambdaQuery(ShopInfo.class)
                .eq(ShopInfo::getPlatform,"Amazon")
                .eq(ShopInfo::getSellerAuthStatus,"SQ01"));
        for(ShopInfo shop : list){

            List<String> marketplaceIds = Arrays.asList(shop.getMarketplaceId().split(","));

            CreateReportSpecification body = new CreateReportSpecification();
            body.setReportType("GET_RESERVED_INVENTORY_DATA");
            body.setMarketplaceIds(marketplaceIds);
            body.setDataStartTime(AmzDateUtils.getOffsetDateTimeUTC(DateUtil.beginOfDay(new Date())));
            body.setDataEndTime(AmzDateUtils.getOffsetDateTimeUTC(new Date()));

//            Calendar cstart=Calendar.getInstance();
//            cstart.add(Calendar.DATE, -360);
//            body.setDataStartTime(AmzDateUtils.getOffsetDateTimeUTC(cstart));
//            Calendar cend=Calendar.getInstance();
//            body.setDataEndTime(AmzDateUtils.getOffsetDateTimeUTC(cend));

            try{
                // 第一步 创建报告
                ReportsApi reportsApi = amazonUtil.getReportsApi(entityAuthority,shop,0.0167);
                final String reportId = createReport(reportsApi, body);
                // 第二步 检验报告是否完成
                ReportsApi reportsApi2 = amazonUtil.getReportsApi(entityAuthority,shop,2.0);
                final Report report = getReport(reportsApi2, reportId);
                // 第三步 获取报告连接
                ReportsApi reportsApi3 = amazonUtil.getReportsApi(entityAuthority,shop,0.0167);
                final ReportDocument reportDocument = reportsApi3.getReportDocument(report.getReportDocumentId());
                // 第四步 下载报告
                String compressionAlgorithm = null;
                if(null != reportDocument.getCompressionAlgorithm()){
                    compressionAlgorithm = reportDocument.getCompressionAlgorithm().getValue();
                }
                tmpList.addAll(downloadReservedInventory(reportDocument.getUrl(),compressionAlgorithm,shop));
            }catch (Exception e){
                log.error("店铺："+shop.getShopName()+" 获取预留库存报告异常",e);
            }
        }
        return tmpList;
    }

    public List<TmpFbaInventory> downloadReservedInventory(String url, String compressionAlgorithm, ShopInfo shop) throws IOException, IllegalArgumentException {
        List<TmpFbaInventory> list = new ArrayList<>();
        OkHttpClient httpclient = new OkHttpClient();
        Request request = new Request.Builder()
                .url(url)
                .get()
                .build();

        Response response = httpclient.newCall(request).execute();
        if (!response.isSuccessful()) {
            System.out.println(
                    String.format("Call to download content was unsuccessful with response code: %d and message: %s",
                            response.code(), response.message()));
            return list;
        }

        try (ResponseBody responseBody = response.body()) {
            MediaType mediaType = MediaType.parse(response.header("Content-Type"));
            Charset charset = mediaType.charset();
            if (charset == null) {
                throw new IllegalArgumentException(String.format(
                        "Could not parse character set from '%s'", mediaType.toString()));
            }

            Closeable closeThis = null;
            try {
                InputStream inputStream = responseBody.byteStream();
                closeThis = inputStream;

                if ("GZIP".equals(compressionAlgorithm)) {
                    inputStream = new GZIPInputStream(inputStream);
                    closeThis = inputStream;
                }

                // This example assumes that the download content has a charset in the content-type header, e.g.
                // text/plain; charset=UTF-8
                if ("text".equals(mediaType.type()) && "plain".equals(mediaType.subtype())) {
                    InputStreamReader inputStreamReader = new InputStreamReader(inputStream, charset);
                    closeThis = inputStreamReader;

                    BufferedReader reader = new BufferedReader(inputStreamReader);
                    closeThis = reader;

                    int lineNumber = 0;
                    String line;
                    Map<String,Integer> titleList = new HashMap<String,Integer>();
//                    List<TmpFbaInventory> list = new ArrayList<>();
                    final Warehouse warehouse = warehouseService.getOne(Wrappers.lambdaQuery(Warehouse.class).eq(Warehouse::getSid, shop.getId()));
                    Long wid = null;
                    if(null != warehouse){
                        wid = warehouse.getId();
                    }
                    while ((line = reader.readLine()) != null) {
                        String[] info = line.split("\t");
                        int length = info.length;
                        if (lineNumber == 0) {
                            for (int i = 0; i < length; i++) {
                                titleList.put(info[i],i);
                            }
                        } else {
                            TmpFbaInventory tmp = new TmpFbaInventory();
                            tmp.setCreateTime(new Date());
                            String sku= GeneralUtil.getStrValue(info, titleList, "sku");
                            String fnsku= GeneralUtil.getStrValue(info, titleList, "fnsku");
                            String asin= GeneralUtil.getStrValue(info, titleList, "asin");
                            String product_name= GeneralUtil.getStrValue(info, titleList, "product-name");
                            Integer reserved_qty= GeneralUtil.getIntegerValue(info, titleList, "reserved_qty");
                            Integer reserved_customerorders= GeneralUtil.getIntegerValue(info, titleList, "reserved_customerorders");
                            Integer reserved_fc_transfers= GeneralUtil.getIntegerValue(info, titleList, "reserved_fc-transfers");
                            Integer reserved_fc_processing= GeneralUtil.getIntegerValue(info, titleList, "reserved_fc-processing");

                            tmp.setWarehouse(wid);
                            tmp.setSid(shop.getId());
                            tmp.setAsin(asin);
                            tmp.setMsku(sku);
                            tmp.setFnsku(fnsku);
//                            tmp.setTotalInventory(reserved_customerorders+reserved_fc_transfers+reserved_fc_processing);
//                            tmp.setAvailableStock(reserved_customerorders+reserved_fc_transfers+reserved_fc_processing);
                            tmp.setWarehouseToBeAdjusted(reserved_fc_transfers);
                            tmp.setDuringWarehouseAdjustment(reserved_fc_processing);
                            tmp.setToBeShipped(reserved_customerorders);

                            list.add(tmp);
                        }
                        lineNumber++;
                        // Process line by line.
                    }
//                    tmpFbaInventoryService.saveBatch(list);
                } else {
                    //Handle content with binary data/other media types here.
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                log.error("处理预留库存报告数据异常",e);
            } finally {
                if (closeThis != null) {
                    closeThis.close();
                }
            }
        }
        return list;
    }

    /**
     * 亚马逊物流库存报告
     * @param
     * @throws Exception
     */
    public void getFbaInventoryAge() throws Exception {
        DatainterfaceAuthority entityAuthority = datainterfaceAuthorityBaseService.getOne(Wrappers.<DatainterfaceAuthority>lambdaQuery().eq(DatainterfaceAuthority::getAppCode,"Amazon"), false);

        final List<ShopInfo> list = shopInfoService.list(Wrappers.lambdaQuery(ShopInfo.class)
                .eq(ShopInfo::getPlatform,"Amazon")
                .eq(ShopInfo::getSellerAuthStatus,"SQ01"));
        for(ShopInfo shop : list){

            List<String> marketplaceIds = Arrays.asList(shop.getMarketplaceId().split(","));

            CreateReportSpecification body = new CreateReportSpecification();
            body.setReportType("GET_FBA_INVENTORY_PLANNING_DATA");
            body.setMarketplaceIds(marketplaceIds);
            body.setDataStartTime(AmzDateUtils.getOffsetDateTimeUTC(DateUtil.beginOfDay(DateUtil.yesterday())));
            body.setDataEndTime(AmzDateUtils.getOffsetDateTimeUTC(DateUtil.endOfDay(DateUtil.yesterday())));

//            Calendar cstart=Calendar.getInstance();
//            cstart.add(Calendar.DATE, -360);
//            body.setDataStartTime(AmzDateUtils.getOffsetDateTimeUTC(cstart));
//            Calendar cend=Calendar.getInstance();
//            body.setDataEndTime(AmzDateUtils.getOffsetDateTimeUTC(cend));

            try {
                // 第一步 创建报告
                ReportsApi reportsApi = amazonUtil.getReportsApi(entityAuthority, shop, 0.0167);
                final String reportId = createReport(reportsApi, body);
                // 第二步 检验报告是否完成
                ReportsApi reportsApi2 = amazonUtil.getReportsApi(entityAuthority, shop, 2.0);
                final Report report = getReport(reportsApi2, reportId);
                // 第三步 获取报告连接
                ReportsApi reportsApi3 = amazonUtil.getReportsApi(entityAuthority, shop, 0.0167);
                final ReportDocument reportDocument = reportsApi3.getReportDocument(report.getReportDocumentId());
                // 第四步 下载报告
                String compressionAlgorithm = null;
                if (null != reportDocument.getCompressionAlgorithm()) {
                    compressionAlgorithm = reportDocument.getCompressionAlgorithm().getValue();
                }
                downloadFbaInventory(reportDocument.getUrl(), compressionAlgorithm, shop);
            }catch (Exception e){
                log.error("店铺："+shop.getShopName()+" 获取亚马逊物流库存报告",e);
            }

        }
    }
    public void downloadFbaInventory(String url, String compressionAlgorithm, ShopInfo shop) throws IOException, IllegalArgumentException {
        OkHttpClient httpclient = new OkHttpClient();
        Request request = new Request.Builder()
                .url(url)
                .get()
                .build();

        Response response = httpclient.newCall(request).execute();
        if (!response.isSuccessful()) {
            System.out.println(
                    String.format("Call to download content was unsuccessful with response code: %d and message: %s",
                            response.code(), response.message()));
            return;
        }

        try (ResponseBody responseBody = response.body()) {
            MediaType mediaType = MediaType.parse(response.header("Content-Type"));
            Charset charset = mediaType.charset();
            if (charset == null) {
                throw new IllegalArgumentException(String.format(
                        "Could not parse character set from '%s'", mediaType.toString()));
            }

            Closeable closeThis = null;
            try {
                InputStream inputStream = responseBody.byteStream();
                closeThis = inputStream;

                if ("GZIP".equals(compressionAlgorithm)) {
                    inputStream = new GZIPInputStream(inputStream);
                    closeThis = inputStream;
                }

                // This example assumes that the download content has a charset in the content-type header, e.g.
                // text/plain; charset=UTF-8
                if ("text".equals(mediaType.type()) && "plain".equals(mediaType.subtype())) {
                    InputStreamReader inputStreamReader = new InputStreamReader(inputStream, charset);
                    closeThis = inputStreamReader;

                    BufferedReader reader = new BufferedReader(inputStreamReader);
                    closeThis = reader;

                    int lineNumber = 0;
                    String line;
                    Map<String,Integer> titleList = new HashMap<String,Integer>();
                    List<TmpFbaInventory> list = new ArrayList<>();
                    final Warehouse warehouse = warehouseService.getOne(Wrappers.lambdaQuery(Warehouse.class).eq(Warehouse::getSid, shop.getId()));
                    Long wid = null;
                    if(null != warehouse){
                        wid = warehouse.getId();
                    }
                    while ((line = reader.readLine()) != null) {
                        String[] info = line.split("\t");
                        int length = info.length;
                        if (lineNumber == 0) {
                            for (int i = 0; i < length; i++) {
                                titleList.put(info[i],i);
                            }
                        } else {
                            TmpFbaInventory tmp = new TmpFbaInventory();
                            tmp.setCreateTime(new Date());
                            String sku= GeneralUtil.getStrValue(info, titleList, "sku");
                            String fnsku= GeneralUtil.getStrValue(info, titleList, "fnsku");
                            String asin= GeneralUtil.getStrValue(info, titleList, "asin");
                            String product_name= GeneralUtil.getStrValue(info, titleList, "product-name");

                            Integer inv_age_0_to_30_days= GeneralUtil.getIntegerValue(info, titleList, "inv-age-0-to-30-days");
                            Integer inv_age_31_to_60_days= GeneralUtil.getIntegerValue(info, titleList, "inv-age-31-to-60-days");
                            Integer inv_age_61_to_90_days= GeneralUtil.getIntegerValue(info, titleList, "inv-age-61-to-90-days");
                            Integer inv_age_91_to_180_days= GeneralUtil.getIntegerValue(info, titleList, "inv-age-91-to-180-days");
                            Integer inv_age_181_to_270_days= GeneralUtil.getIntegerValue(info, titleList, "inv-age-181-to-270-days");
                            Integer inv_age_271_to_365_days= GeneralUtil.getIntegerValue(info, titleList, "inv-age-271-to-365-days");
                            Integer inv_age_365_plus_days= GeneralUtil.getIntegerValue(info, titleList, "inv-age-365-plus-days");

                            tmp.setWarehouse(wid);
                            tmp.setSid(shop.getId());
                            tmp.setAsin(asin);
                            tmp.setMsku(sku);
                            tmp.setFnsku(fnsku);
                            tmp.setDay30(inv_age_0_to_30_days);
                            tmp.setDay60(inv_age_31_to_60_days);
                            tmp.setDay90(inv_age_61_to_90_days);
                            tmp.setDay180(inv_age_91_to_180_days);
                            tmp.setDay270(inv_age_181_to_270_days);
                            tmp.setDay365(inv_age_271_to_365_days);
                            tmp.setDay366(inv_age_365_plus_days);

                            list.add(tmp);
                        }
                        lineNumber++;
                        // Process line by line.
                    }
                    tmpFbaInventoryService.saveBatch(list);
                } else {
                    //Handle content with binary data/other media types here.
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                log.error("处理预留库存报告数据异常",e);
            } finally {
                if (closeThis != null) {
                    closeThis.close();
                }
            }
        }
    }
}
